{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Estimating overall rates and yields from pseudo batch transformed data" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "This tutorial will show how to use the fedbatch data correction package to calculate rates and yields from measurements. We will use simulated data to showcase the workflow. The simulated data here resembles a system where online measurements are available. This could for example to the Satorious AMBR(R) or M2Lab Bio/Robolector cultivation systems." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## loading fedbatch data" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/s143838/.virtualenvs/pseudobatch-dev/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "{'stan_version_major': '2', 'stan_version_minor': '29', 'stan_version_patch': '2', 'STAN_THREADS': 'false', 'STAN_MPI': 'false', 'STAN_OPENCL': 'false', 'STAN_NO_RANGE_CHECKS': 'false', 'STAN_CPP_OPTIMS': 'false'}\n" ] } ], "source": [ "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import numpy as np\n", "import seaborn as sns\n", "from patsy import dmatrices\n", "import statsmodels.api as sm\n", "\n", "from pseudobatch import pseudobatch_transform_pandas\n", "from pseudobatch.datasets import load_standard_fedbatch" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "First, we will load the standard fed-batch process dataset and take only the time points where a sample was take" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "fedbatch_df_measurement = load_standard_fedbatch(sampling_points_only=True)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Lets start with getting an overview of the data that we have imported by look at a part of the dataframe." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
timestampsample_volumec_Biomassc_Glucosec_Productv_Volumev_Feed_accum
010.000000170.01.3378520.0750160.6947351015.90603615.906036
117.142857170.02.6640230.0751031.794378867.75351337.753513
224.285714170.05.1757670.0750533.877080733.63887273.638872
331.428571170.09.6122840.0750157.555778619.956743129.956743
438.571429170.016.5619670.07501113.318358533.452797213.452797
\n", "
" ], "text/plain": [ " timestamp sample_volume c_Biomass c_Glucose c_Product v_Volume \n", "0 10.000000 170.0 1.337852 0.075016 0.694735 1015.906036 \\\n", "1 17.142857 170.0 2.664023 0.075103 1.794378 867.753513 \n", "2 24.285714 170.0 5.175767 0.075053 3.877080 733.638872 \n", "3 31.428571 170.0 9.612284 0.075015 7.555778 619.956743 \n", "4 38.571429 170.0 16.561967 0.075011 13.318358 533.452797 \n", "\n", " v_Feed_accum \n", "0 15.906036 \n", "1 37.753513 \n", "2 73.638872 \n", "3 129.956743 \n", "4 213.452797 " ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(fedbatch_df_measurement\n", " .filter(['timestamp', 'sample_volume', 'c_Biomass', 'c_Glucose', 'c_Product', 'v_Volume', 'v_Feed_accum'])\n", " .head()\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "This shows some of the columns in the dataframe. \n", "- `sample_volume` columns contain the sample volume at the given time point. In this dataset, we have online measurements thus more measurements than samples and therefore at most timepoint the sample volume is 0.\n", "- `timestamp` describe the timepoint\n", "- `c_Biomass`, `c_Glucose`, and `c_Product` is the online concentration measurements \n", "- `v_Volume` is the volume of the bioreactor. **IMPORTANT:** at points where a sample is taken this value represents the volume just **before** the sample was drawn.\n", "- `v_Feed_accum` is the accumulated feed added until that timepoint.\n", "- `m_Biomass`, `m_Glucose`, `m_Product` is the total mass of that species in the reactor, i.e. volume * concentration\n", "\n", "The dataframe does contain more columns than those shown, but these simply contain information about the parameters used for simulation. Some of them, e.g. true maximum growth rate, are typically not know in a real experimental setting and some of them are experimental design parameters, e.g. glucose concentration in the feed. For clarity, we will just print them here:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAB8YAAAGRCAYAAAAXXNklAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAC3T0lEQVR4nOzde3yP9f/H8edns4PD9plh+2wZ5hDmmBVGKRpzSGQlIocWpSGUav2EUU1EJFF9nQrNV1/0dWgMoZhzyqGEJr7Zplo2h7bZdv3+cNsnH9sYdt7jfrtdN673+31d1+v6bHu/P+/rfV3vy2QYhiEAAAAAAAAAAAAAAEopu6IOAAAAAAAAAAAAAACAgsTAOAAAAAAAAAAAAACgVGNgHAAAAAAAAAAAAABQqjEwDgAAAAAAAAAAAAAo1RgYBwAAAAAAAAAAAACUagyMAwAAAAAAAAAAAABKNQbGAQAAAAAAAAAAAAClGgPjAAAAAAAAAAAAAIBSjYFxAAAAAAAAAAAAAECpxsA4Sr2JEyfKZDIVdRgAgFLIZDJp4sSJRR0GAADZ0A8CANxIrVq1NGjQoKIOAwBQQpw6dUomk0mLFi0q6lCAO8LAOEqkWrVqyWQyWRdnZ2fVq1dPY8eOVWJiYlGHBwAooTIzM/Xpp5+qY8eOqlq1qhwcHOTh4aFOnTrp448/VmpqalGHCAAoIa7vs3h4eOiBBx7QqlWrijq0fHH06FFNnDhRp06dKupQAKBUmzFjhkwmkzZt2pRrmU8++UQmk0n//e9/CzEyAEBByxqMzmlp3bp1UYcHlEjlijoA4HY1b95cL730kiQpJSVF+/fv18yZM7Vt2zbt2bPHWm7cuHF67bXXiipMAEAJ8ffff+uxxx7Thg0b1KZNG7388svy9PRUYmKitm3bphdeeEG7d+/W/PnzizpUAEAJcW2f5ezZs/roo4/Uq1cvzZ07V88//3wRR3dnjh49qvDwcD300EOqVatWUYcDAKVWnz59NHbsWC1btkyBgYE5llm2bJmqVKmiLl26FHJ0AIDC0LdvX3Xt2tUmrVq1akUUDVCyMTCOEuuuu+5S//79revPPvusKlWqpHfffVfHjx9XvXr1JEnlypVTuXL8qgMAbmz06NHasGGDZs6cqRdffNEm76WXXtLx48cVHR1dRNEBAEqi6/ssAwYMUN26dfXee+/lOjCenp6uzMxMOTo6FlaYAIBizNvbW+3bt9fKlSs1d+5cOTk52eT/9ttv2r59u4YOHSoHB4ciihIAUJBatGhh068AcPuYSh1F4rffflNISIi8vb3l5OQkX19fDRs2TGlpaXe0X4vFIkk2A+E5vVsvPT1dkydPVp06deTk5KRatWrp9ddfzzZFbq1atfTII49o69atuvfee1W+fHk1adJEW7dulSStXLlSTZo0kbOzs/z9/fXdd9/ZbP/DDz9o0KBBql27tpydnWWxWPTMM8/ozz//tCl34cIFjRo1SrVq1ZKTk5M8PDzUsWNHHThwwFrm+PHjCg4OlsVikbOzs6pXr64+ffooKSnpjj4zACgt7qRtOXPmjP71r3+pc+fO2QbFs9SrV08vvPDCDfczaNCgHJ+ay+09r0uWLFHLli1VoUIFVa5cWe3atdPGjRttynz44Ydq1KiRnJyc5O3trdDQUJ0/f96mTF7biCVLlsjf31/ly5eXu7u7+vTpozNnztzwnACgrCqIPovFYlHDhg0VGxsr6Z+pEd99913NnDnT2j85evSoJGnLli164IEHVLFiRbm5ualHjx768ccfs+3322+/1X333SdnZ2fVqVNHH330UbYyN3onoMlk0sSJE/N8/osWLdITTzwhSWrfvr11OsesfhIA4KovvvhCJpNJ27Zty5b30UcfyWQy6fDhwzfdT//+/ZWUlKR169Zly4uMjFRmZqb69esnSbp06ZJeeukl+fj4yMnJSfXr19e7774rwzBueIzc+iyLFi2SyWSyeXXGnV4vk6SffvpJjz/+uNzd3eXs7Kx7772XqeABlBr5Vf/nVV7r1PPnz2vUqFHWNqJu3bp65513lJmZma3coEGDZDab5ebmpoEDB2a7FpUXaWlpGj9+vPz9/WU2m1WxYkU98MAD+vrrr7OVzczM1KxZs6ztR7Vq1dS5c2ft27fPptzNrqXl1LeRrrZdgwYNsq5ntW/ffvutRo4cqWrVqsnNzU3PPfec0tLSdP78eQ0YMECVK1dW5cqV9corr9y0LUXJwGO0KHRnz55Vy5Ytdf78eQ0dOlQNGjTQb7/9pi+++EKXL1/O85MRV65c0R9//CHp6lTq3333nWbMmKF27drJ19f3hts+++yzWrx4sR5//HG99NJL2r17tyIiIvTjjz9me+ffiRMn9NRTT+m5555T//799e6776p79+6aN2+eXn/9desgSUREhHr37q1jx47Jzu7qPSfR0dH65ZdfNHjwYFksFh05ckQff/yxjhw5ol27dlk7HM8//7y++OILDR8+XH5+fvrzzz/17bff6scff1SLFi2UlpamoKAgpaamasSIEbJYLPrtt9+0du1anT9/Xmaz+ZZ+BgBQ2txp2/LVV18pIyOjUO++DQ8P18SJE9WmTRtNmjRJjo6O2r17t7Zs2aJOnTpJunpxKjw8XIGBgRo2bJiOHTumuXPnau/evdqxY4ccHBzy3Ea89dZbeuONN9S7d289++yz+v333zV79my1a9dO3333ndzc3Art3AGguMuvPsv1rly5ojNnzqhKlSo26QsXLlRKSoqGDh0qJycnubu7a9OmTerSpYtq166tiRMn6u+//9bs2bPVtm1bHThwwHoj1qFDh9SpUydVq1ZNEydOVHp6uiZMmCBPT88CO/927dpp5MiRev/99/X666+rYcOGkmT9FwBwVbdu3VSpUiX9+9//1oMPPmiTt3z5cjVq1EiNGze+6X569eqlYcOGadmyZerVq5dN3rJly1SzZk21bdtWhmHo0Ucf1ddff62QkBA1b95cGzZs0NixY/Xbb7/pvffey7dzu5PrZUeOHFHbtm1111136bXXXlPFihX173//Wz179tR//vMfPfbYY/kWJwAUhfyq/7NcvnzZOhaSxWw2y8HBIc916uXLl/Xggw/qt99+03PPPacaNWpo586dCgsLU1xcnGbOnClJMgxDPXr00Lfffqvnn39eDRs21KpVqzRw4MBb/hySk5P1r3/9S3379tWQIUN04cIFzZ8/X0FBQdqzZ4+aN29uLRsSEqJFixapS5cuevbZZ5Wenq5vvvlGu3bt0r333ispb9fSblXWtbTw8HDt2rVLH3/8sdzc3LRz507VqFFDb7/9ttavX69p06apcePGGjBgwG0dB8WIARSyAQMGGHZ2dsbevXuz5WVmZuZpHzVr1jQkZVvatm1r/PHHHzZlJ0yYYFz7q37w4EFDkvHss8/alHv55ZcNScaWLVuyHWfnzp3WtA0bNhiSjPLlyxu//vqrNf2jjz4yJBlff/21Ne3y5cvZYv/8888NScb27dutaWaz2QgNDc31fL/77jtDkrFixYobfCoAUHbdadsyevRoQ5Jx8OBBm/TU1FTj999/ty7XtzGSjAkT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XcuXL9fy5cvVsmXLbK/RyIu2bduqVq1aWrJkiZYvX64HH3zQZhbBrl27KiMjI1uf5r333pPJZLJ5+OJ6derUkSSbduLSpUtavHjxLcd5Ix4eHnrooYf00Ucf5ThI8fvvv+fr8QCgKOVX/Z+bW6lTe/furZiYmGz9BOnqd/qsa0tdu3ZVenq65s6da83PyMjQ7Nmzbzm+nMZIdu/erZiYGJtywcHBMgxD4eHh2faRtW1erqVJV9uz6/s8H3/8MTNlwYonxlHo3n77bW3cuFEPPvighg4dqoYNGyouLk4rVqzQt99+m+M793Ly22+/Wae1TUtL0/fff6+PPvpIVatWveE06s2aNdPAgQP18ccf6/z583rwwQe1Z88eLV68WD179lT79u3z4zTl6uqqdu3aaerUqbpy5Yruuusubdy4UbGxsTblLly4oOrVq+vxxx9Xs2bNVKlSJW3atEl79+7V9OnTJUlbtmzR8OHD9cQTT+juu+9Wenq6PvvsM9nb2ys4ODhf4gWAkiw/2paZM2cqNjZWI0aMUGRkpLp37y4PDw/98ccf2rFjh9asWXPT9yn16dNHr776qh577DGNHDlSly9f1ty5c3X33XfrwIED1nJ169bV//3f/2ny5Ml64IEH1KtXLzk5OWnv3r3y9vZWRESEqlWrprCwMIWHh6tz58569NFHdezYMX344Ye677771L9/f0l5ayPq1KmjN998U2FhYTp16pR69uwpFxcXxcbGatWqVRo6dKhefvnl2/8BAEApk199ljsxbdo0denSRQEBAQoJCdHff/+t2bNny2w2a+LEidZy4eHhioqK0gMPPKAXXnhB6enpmj17tho1amRzo5YkPfvss5oyZYqeffZZ3Xvvvdq+fbt+/vnnbMfOy/k3b95c9vb2euedd5SUlCQnJyd16NBBHh4eBf3RAECJ4+DgoF69eikyMlKXLl3Su+++e1v7MZlMeuqpp6zT8E6aNMkmv3v37mrfvr3+7//+T6dOnVKzZs20ceNGffnllxo1apR18DsnnTp1Uo0aNRQSEqKxY8fK3t5eCxYsULVq1WxuvsoPc+bM0f33368mTZpoyJAhql27thISEhQTE6P//e9/+v777/P1eABQVPKr/r+RvNapY8eO1X//+1898sgjGjRokPz9/XXp0iUdOnRIX3zxhU6dOqWqVauqe/fuatu2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dZfmzJlzw5jPnDmj3r17y83NTe7u7urRo4dOnTqVa/mtW7fKZDJpw4YNuueee1S+fHl16NBB586d01dffaWGDRvK1dVVTz31lM37HDMzMxURESFfX1+VL19ezZo10xdffGHNz8jIUEhIiDW/fv36mjVrVrZjt2zZUhUrVpSbm5vatm2rX3/9VZI0aNAg9ezZ06b8qFGj9NBDD1nXH3roIQ0fPlyjRo1S1apVFRQUJEk6fPiwunTpokqVKsnT01NPP/20/vjjD5vtRowYoVGjRqly5cry9PTUJ598okuXLmnw4MFycXFR3bp19dVXX9kcPy/7HTlypF555RW5u7vLYrFo4sSJ1vxatWpJkh577DGZTCbrOoqHlr7u8jI7K7evhiZJXuarXyCB28Hv2O2h7aftp+0vezIzM5Wamppj3sGDByVJXl5ehRjRjVFPUU9RT6Eg8R2y5OJnV3rR9tP20/ajJKCuoq6irkJBKarvuWVuYDzqcJyGLTmQbd76+KQUDVtyoEAq9EqVKqlSpUpavXp1rhfnJMnOzk7vv/++jhw5osWLF2vLli165ZVXbMpcvnxZ77//viIjIxUVFaWtW7fqscce0/r167V+/Xp99tln+uijj2wqREmaNm2amjVrpu+++06vvfaaXnzxRUVHR+cYx5UrVxQUFCQXFxd988032rFjhypVqqTOnTsrLS3thuc6ceJEffDBB9q5c6e1QZg5c6aWLVumdevWaePGjZo9e7a1fEREhD799FPNmzdPR44c0ejRo9W/f39t27ZN0tXKvnr16lqxYoWOHj2q8ePH6/XXX9e///1vSVJ6erp69uypBx98UD/88INiYmI0dOhQmUy3dsfa4sWL5ejoqB07dmjevHk6f/68OnTooHvuuUf79u1TVFSUEhIS1Lt372zbVa1aVXv27NGIESM0bNgwPfHEE2rTpo0OHDigTp066emnn7Y2YLey34oVK2r37t2aOnWqJk2aZP157d27V5K0cOFCxcXFWddRPNjbmTSh+9X3mV7/W5i1PqG7X4HeVXm9OXPmqFatWnJ2dlarVq20Z8+eG5ZfsWKFGjRoIGdnZzVp0kTr16+3yTeZTDku06ZNs5apVatWtvwpU6ZY81NSUjRo0CA1adJE5cqVy/alK8vWrVvVokULOTk5qW7dulq0aNFtfw6lRXH8HSvuaPtp+3NC21+6hIWFafv27Tp16pQOHTqksLAwbd26Vf369dPJkyc1efJk7d+/X6dOndJ///tfDRgwQO3atVPTpk2LOnRJ1FPUUzmjnkJ+KivfIbdv367u3bvL29s7x2kzDcPQ+PHj5eXlpfLlyyswMFDHjx+3KZOYmKh+/frJ1dVVbm5uCgkJsbnQLkk//PCDHnjgATk7O8vHx0dTp04tsHMqKz+7soa2n7Y/J7T9KG6oq6irckJdhfxSZN9zjWImKSnJkGQkJSVly/v777+No0ePGn///fdt7Ts9I9No/fYmo+ara3Ncar261mj99iYjPSPzTk8jmy+++MKoXLmy4ezsbLRp08YICwszvv/++xtus2LFCqNKlSrW9YULFxqSjBMnTljTnnvuOaNChQrGhQsXrGlBQUHGc889Z12vWbOm0blzZ5t9P/nkk0aXLl2s65KMVatWGYZhGJ999plRv359IzPzn88hNTXVKF++vLFhw4YcY/36668NScamTZusaREREYYk4+TJkzbxBgUFGYZhGCkpKUaFChWMnTt32uwrJCTE6Nu3b66fS2hoqBEcHGwYhmH8+eefhiRj69atOZYdOHCg0aNHD5u0F1980XjwwQet6w8++KBxzz332JSZPHmy0alTJ5u0M2fOGJKMY8eOWbe7//77rfnp6elGxYoVjaefftqaFhcXZ0gyYmJibnu/hmEY9913n/Hqq69a16/9eeXmTv9ecGe+OnQ2W33T+u1NxleHzuZp+xvVhbciMjLScHR0NBYsWGAcOXLEGDJkiOHm5mYkJCTkWH7Hjh2Gvb29MXXqVOPo0aPGuHHjDAcHB+PQoUPWMnFxcTbLggULDJPJZPO3XrNmTWPSpEk25S5evGjNv3jxovH8888bH3/8sREUFJTt79QwDOOXX34xKlSoYIwZM8Y4evSoMXv2bMPe3t6IiorK8/nn1+dYHN3p71hJQdtP228YtP2GcfO2/0Z/K6W5LszyzDPPGDVr1jQcHR2NatWqGQ8//LCxceNGwzAM4/Tp00a7du0Md3d3w8nJyahbt64xduzYW/48CqqfQj31D+qpB63rpbGeMgz6KMVBcemnFJT169cb//d//2esXLkyx9/JKVOmGGaz2Vi9erXx/fffG48++qjh6+tr8zvZuXNno1mzZsauXbuMb775xqhbt67N339SUpLh6elp9OvXzzh8+LDx+eefG+XLlzc++uijPMd5O59jWfn+X1LQ9tP20/bfedtf3NuUkoJ+ylXUVTmjrqKfUhLkx/fcW2lTytQ7xvfEJma7u+lahqS4pBTtiU1UQJ0q+Xrs4OBgdevWTd9884127dqlr776SlOnTtW//vUvDRo0SJK0adMmRURE6KefflJycrLS09OVkpKiy5cvq0KFCpKkChUq2LwH0dPTU7Vq1VKlSpVs0s6dO2dz/ICAgGzrM2fOzDHW77//XidOnJCLi4tNekpKik6ePHnD87z2qRtPT09VqFBBtWvXtknLelr1xIkTunz5sjp27Gizj7S0NN1zzz3W9Tlz5mjBggU6ffq0/v77b6Wlpal58+aSJHd3dw0aNEhBQUHq2LGjAgMD1bt371ueFtPf399m/fvvv9fXX39t87lmOXnypO6+++5s52tvb68qVaqoSZMmNucryfrzuJ39Slen+bz+Z4rirXNjL3X0sxTq+3dyMmPGDA0ZMkSDBw+WJM2bN0/r1q3TggUL9Nprr2UrP2vWLHXu3Fljx46VJE2ePFnR0dH64IMPNG/ePEmSxWKx2ebLL79U+/btbf7WJcnFxSVb2SwVK1bU3LlzJUk7duzQ+fPns5WZN2+efH19NX36dElSw4YN9e233+q9996zTtNTlhWX37Hijrbfdp22/x+0/aXL/Pnzc83z8fGx3kFfHFFP2a5TT/2DegoFobR/h+zSpYu6dOmSY55hGJo5c6bGjRunHj16SJI+/fRTeXp6avXq1erTp49+/PFHRUVFae/evbr33nslSbNnz1bXrl317rvvytvbW0uXLlVaWpoWLFggR0dHNWrUSAcPHtSMGTM0dOjQAju30v6zK0to+23Xafv/QduP4oS6ynaduuof1FXIb4X9PbdMDYyfu5B7RX475W6Vs7OzOnbsqI4dO+qNN97Qs88+qwkTJmjQoEE6deqUHnnkEQ0bNkxvvfWW3N3d9e233yokJERpaWnWytzBwcFmnyaTKce0zMzM247z4sWL8vf319KlS7PlVatW7YbbXhvLzWLLmops3bp1uuuuu2zKOTk5SZIiIyP18ssva/r06QoICJCLi4umTZum3bt3W8suXLhQI0eOVFRUlJYvX65x48YpOjparVu3lp2dnQzDsNn3lStXssVdsWLFbJ9B9+7d9c4772Qre21DcbOfR9Y0JNee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ytPTU6tXr1afPn30448/KioqSnv37tW9994rSZo9e7a6du2qd999V97e3oV7UgBQBvDEOAAAAAAAAAAAQB7997//1b333qsnnnhCHh4euueee/TJJ59Y82NjYxUfH6/AwEBrmtlsVqtWrRQTEyNJiomJkZubm3VQXJICAwNlZ2en3bt3F97JAEAZwsA4AAAAAAAAAABAHv3yyy+aO3eu6tWrpw0bNmjYsGEaOXKkFi9eLEmKj4+XJHl6etps5+npac2Lj4+Xh4eHTX65cuXk7u5uLXO91NRUJScn2ywAgLxjKnUAAAAAAAAAAIA8yszM1L333qu3335bknTPPffo8OHDmjdvngYOHFhgx42IiFB4eHiB7R8ASjueGAcAAABQos2dO1dNmzaVq6urXF1dFRAQoK+++sqan5KSotDQUFWpUkWVKlVScHCwEhISijBiAAAAACWZl5eX/Pz8bNIaNmyo06dPS5IsFoskZet3JCQkWPMsFovOnTtnk5+enq7ExERrmeuFhYUpKSnJupw5cyZfzgcAygoGxgEAAACUaNWrV9eUKVO0f/9+7du3Tx06dFCPHj105MgRSdLo0aO1Zs0arVixQtu2bdPZs2fVq1evIo4aAAAAQEnVtm1bHTt2zCbt559/Vs2aNSVJvr6+slgs2rx5szU/OTlZu3fvVkBAgCQpICBA58+f1/79+61ltmzZoszMTLVq1SrH4zo5OVlvCM5aAAB5x1TqAAAAAEq07t2726y/9dZbmjt3rnbt2qXq1atr/vz5WrZsmTp06CBJWrhwoRo2bKhdu3apdevWRREyAAAAgBJs9OjRatOmjd5++2317t1be/bs0ccff6yPP/5YkmQymTRq1Ci9+eabqlevnnx9ffXGG2/I29tbPXv2lHT1CfPOnTtryJAhmjdvnq5cuaLhw4erT58+8vb2LsKzA4DSiyfGAQAAAJQaGRkZioyM1KVLlxQQEKD9+/frypUrCgwMtJZp0KCBatSooZiYmCKMFAAAAEBJdd9992nVqlX6/PPP1bhxY02ePFkzZ85Uv379rGVeeeUVjRgxQkOHDtV9992nixcvKioqSs7OztYyS5cuVYMGDfTwww+ra9euuv/++62D6wCA/McT4wAAAABKvEOHDikgIEApKSmqVKmSVq1aJT8/Px08eFCOjo5yc3OzKe/p6an4+Phc95ea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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_columns = [\"c_Biomass\", \"c_Glucose\", \"c_Product\", \"v_Volume\", \"v_Feed_accum\"]\n", "\n", "fig, axes = plt.subplots(nrows = 1, ncols = len(plot_columns), figsize=(20, 4))\n", "for ax, column in zip(axes.ravel(), plot_columns):\n", " ax.scatter(fedbatch_df_measurement[\"timestamp\"], fedbatch_df_measurement[column], label=\"Sample measurement\")\n", " ax.title.set_text(column)\n", " ax.legend()\n", "fig.supxlabel(\"Feeding time [h]\")\n", "fig.tight_layout()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "In the simulated data, we clearly see the discrete nature of the product, glucose and biomass mass' and the volume of bioreactor. This is due to sample withdrawal of reactor. This \"continuos\" time series would be available for some quantities, such as Biomass, O2, CO2, and volume, in some cultivation systems, e.g. Robolector or AMBR systems. Glucose and product measurements will typically only be available as the much sparser measurement points. The pseudo batch transformation can handle both online measurements and sample measurements." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Applying the pseudo batch transformation" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now we can transform the data. Here I will use a convenience wrapper function that can be applied directly to a Pandas DataFrame, but under the hood this just loops over a list of columns and calls the `pseudobatch_transform()` on each of them." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "glucose_in_feed = 100\n", "\n", "fedbatch_df_measurement[[\"c_Biomass_pseudo\", \"c_Glucose_pseudo\", \"c_Product_pseudo\", \"c_CO2_pseudo\"]] = pseudobatch_transform_pandas(\n", " fedbatch_df_measurement,\n", " measured_concentration_colnames=[\"c_Biomass\", \"c_Glucose\", \"c_Product\", \"c_CO2\"],\n", " reactor_volume_colname=\"v_Volume\",\n", " accumulated_feed_colname=\"v_Feed_accum\",\n", " sample_volume_colname=\"sample_volume\",\n", " concentration_in_feed=[0, glucose_in_feed, 0, 0],\n", ")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Calculate growth rate" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now we are ready to estimate the growth rate. To estimate the growth rate we will use a log-linear model.\n", "$$\n", "log(C^{\\star}_{Biomass}) = a + \\hat\\mu * t\n", "$$\n", "where $C^{\\star}_{Biomass}$ is the pseudo batch transformed biomass concentration, and $\\hat\\mu$ is the growth rate estimate. Because we will fit several linear models, we make a small convenience function to simplify the code." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "def fit_ols_model(formula_like: str, data: pd.DataFrame) -> sm.regression.linear_model.RegressionResultsWrapper:\n", " y, X = dmatrices(formula_like, data)\n", " model = sm.OLS(endog=y, exog=X)\n", " res = model.fit()\n", " return res" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now we can fit the growth rate for both the pseudo batch transformed and the raw biomass data." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitted growth rate from pseudo batch transformed biomass: 0.10000027170275563\n", "Fitted growth rate from raw biomass: 0.05468160932419806\n", "True simulated growth rate 0.1000107311536732\n" ] } ], "source": [ "# fitting a linear model to the pseudo batch transformed biomass\n", "res_mu_hat_pseudo = fit_ols_model(\"np.log(c_Biomass_pseudo) ~ timestamp\", fedbatch_df_measurement)\n", "\n", "# fitting a linear model to the raw biomass\n", "res_mu_hat_raw = fit_ols_model(\"np.log(m_Biomass) ~ timestamp\", fedbatch_df_measurement)\n", "\n", "# save the growth rate estimates\n", "mu_hat_pseudo = res_mu_hat_pseudo.params[1]\n", "mu_hat_raw = res_mu_hat_raw.params[1]\n", "\n", "print(\"Fitted growth rate from pseudo batch transformed biomass: \" + str(mu_hat_pseudo))\n", "print(\"Fitted growth rate from raw biomass: \" + str(mu_hat_raw))\n", "print(\"True simulated growth rate \" + str(fedbatch_df_measurement[\"mu_true\"].iloc[-1]))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "We see that the growth rate fitted to the pseudo batch data is very close to the true growth rate. The small difference originates from the fact that the growth rate in the simulation is not truly constant, but changes slightly due to substrate concentration changing slightly. On the other hand the growth rate estimate from the raw measurements in very wrong." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Estimating biomass yield coefficients\n", "The biomass yield coefficients can also be estimated from the pseudo batch transformed data. Here we will fit a normal linear model to obtain a single overall yield estimate for each species.\n", "$$\n", "C^{\\star}_{Species} = a + \\hat Y_{xspecies} * C^{\\star}_{Biomass}\n", "$$\n", "\n", "Where $C^{\\star}_{Species}$ is the pseudo concetration of a species and the $\\hat Y_{xspecies}$ is the biomass yield coefficient (in units $\\frac{g_{Species}}{g_{Biomass}}$)." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "We will start by estimating the substrate biomass yield coefficient. Also we will use the convention that yield coefficients are strictly positive." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitted Yxs from pseudo batch transformed data: 1.85\n", "True Yxs: 1.85\n" ] } ], "source": [ "# res_yxs_noncorrected = fit_ols_model(formula_like = \"m_Glucose_consumed ~ m_Biomass\", data= fedbatch_df_measurement)\n", "res_yxs_corrected = fit_ols_model(formula_like = \"c_Glucose_pseudo ~ c_Biomass_pseudo\", data= fedbatch_df_measurement)\n", "\n", "# yxs_noncorrected = res_yxs_noncorrected.params[1]\n", "yxs_corrected = np.abs(res_yxs_corrected.params[1])\n", "\n", "# print(f\"Fitted Yxs from raw data: {yxs_noncorrected.round(5)}\")\n", "print(f\"Fitted Yxs from pseudo batch transformed data: {yxs_corrected.round(5)}\")\n", "print(f\"True Yxs: {fedbatch_df_measurement.Yxs.iloc[0].round(5)}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "To estimate the biomass yield of a substrate using the raw data we first need to calculate the consumed substrate (notice that this was NOT required using the pseudo batch transformed data). For the sake brevity we will skip this calculation in the tutorial to see how it can be done please refer to [this notebook](../../../article/notebooks/2.0-vikhes-investigate-test-data-set.ipynb). " ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now let's move on the product biomass yield coefficient." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitted Yxp from raw data: 0.83926\n", "Fitted Yxp from pseudo batch transformed data: 0.82151\n", "True Yxp: 0.82151\n" ] } ], "source": [ "res_yxp_noncorrected = fit_ols_model(formula_like = \"m_Product ~ m_Biomass\", data= fedbatch_df_measurement)\n", "res_yxp_corrected = fit_ols_model(formula_like = \"c_Product_pseudo ~ c_Biomass_pseudo\", data= fedbatch_df_measurement)\n", "\n", "yxp_noncorrected = res_yxp_noncorrected.params[1]\n", "yxp_corrected = res_yxp_corrected.params[1]\n", "\n", "print(f\"Fitted Yxp from raw data: {yxp_noncorrected.round(5)}\")\n", "print(f\"Fitted Yxp from pseudo batch transformed data: {yxp_corrected.round(5)}\")\n", "print(f\"True Yxp: {fedbatch_df_measurement.Yxp.iloc[0].round(5)}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Again the estimate based on the pseudo batch transformed data is more accurate that the estimate based on the raw data. In this case the difference the improvement of the estimate with the pseudo batch data is not as significant as for the growth rate, never the less it is still more accurate." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Overall specific uptake/secretion rates\n", "Once we have calculated the yields and the growth rate it is easy to calculate the remaining uptake/secretion rates ($r_{species}$) assuming that the consumption and production is growth coupled.\n", "\n", "$$\n", "r_{species} = \\mu * Y_{xspecies}\n", "$$" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Lets start with the specific production rate" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitted r_p from pseudo batch transformed data: 0.08215\n", "Fitted r_p from raw data: 0.04589\n", "True r_p: 0.08216\n" ] } ], "source": [ "r_p_corrected = mu_hat_pseudo * yxp_corrected\n", "r_p_raw = mu_hat_raw * yxp_noncorrected\n", "r_p_true = fedbatch_df_measurement.mu_true.iloc[0] * fedbatch_df_measurement.Yxp.iloc[0]\n", "\n", "print(f\"Fitted r_p from pseudo batch transformed data: {r_p_corrected.round(5)}\")\n", "print(f\"Fitted r_p from raw data: {r_p_raw.round(5)}\")\n", "print(f\"True r_p: {r_p_true.round(5)}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "And the specific glucose uptake rate" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fitted r_s from pseudo batch transformed data: 0.185\n", "True r_s: 0.18503\n" ] } ], "source": [ "r_s_corrected = mu_hat_pseudo * yxs_corrected\n", "r_s_true = fedbatch_df_measurement.mu_true.iloc[0] * fedbatch_df_measurement.Yxs.iloc[0]\n", "\n", "print(f\"Fitted r_s from pseudo batch transformed data: {r_s_corrected.round(5)}\")\n", "print(f\"True r_s: {r_s_true.round(5)}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "The specific rates calculated from the pseudo batch transformed data is correct to the four decimal point. Where as the specific rates calculated from the non corrected data are incorrect. In the next tutorial we will show how time series estimates of rates and yields based on pseudo batch transformed data. Continue [here](./3%20-%20Estimate%20time%20series%20parameters.ipynb)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.8.5 ('.venv_fedbatch-data-correction': venv)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.8" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "0337f5dfa8bf2ee335f62d4679bbb5183dd2c214a8c6ed07ec0592e911fc9b16" } } }, "nbformat": 4, "nbformat_minor": 2 }